fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

#[derive(Debug)]
struct Import<'a> {
    part: &'a str,
}

#[derive(Debug)]
struct Person {
    name: String,
}

fn main() {
    // 生命期是rust用来解决引用有效性问题的。
    // 当编译期，rustc不能确定引用是否有效时，让程序员来手动确认引用的有效期。
    
    let s1 = "abcd";
    let s2 = "abcde";

    // 提示需要手动指定borrowed有效期。
    let ret = longest(&s1, &s2);
    println!("Longest is {}", ret);


    // 可以通过的场景，参数1比参数2长，返回任何一个小于等于其
    // 中的任何一个，所以可以编译
    let s3 = String::from("aaaa");
    {
        let s4 = String::from("aaa");
        let result = longest(&s3, &s4);
        println!("result: {}", result);
    }

    // 不能通过
    let s5 = "b";
    let result;
    {
        let s6 = String::from("bb");
        // 将会报错
        // result = longest(&s5, s6.as_str());
        
        // 这个可以，因为是在栈上分配的，并且它的引用是安全的，因为str是只读的.
        let s7 = "aaaa";
        result = longest(&s5, &s7);
        println!("Address: {:p}", s7); 
    }
    println!("longest: {}, address: {:p}", result, result);
    test_struct();

}

fn test_struct() -> &'static Person {

    // struct中的lifetime
    let name = "hello";
    let mut i = Import{part: &name};
    println!("name: {}", name);
    println!("struct: {:?}", i);
    i.part = &"b";
    println!("name: {}", name);

    let mut p = get_person("lin".to_string());
    println!("person is {:?}, name: {}", p, p.name);
    p.name = "hello".to_string();
    println!("person is {:?}, name: {}", p, p.name);
    // 编译失败，因为p只在当前函数中，返回时就会被释放，生存期失效了。
    &p
}

fn get_person(name: String) -> Person {
    Person{name: name}
}
